package com.android.yinghebike.ui.activity;

import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.Settings;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.baselibrary.interface_.CommCallBack;
import com.android.baselibrary.tool.CommToast;
import com.android.baselibrary.tool.Log;
import com.android.baselibrary.tool.XXPermisionUtil;
import com.android.baselibrary.util.FileUriUtil;
import com.android.baselibrary.util.Util;
import com.android.baselibrary.view.Comm_HeadView;
import com.android.baselibrary.view.Comm_SubmitBtnView;
import com.android.baselibrary.view.Comm_TitleView;
import com.android.yinghebike.R;
import com.android.yinghebike.adapter.LogAdapter;
import com.android.yinghebike.manager.BleManager;
import com.android.yinghebike.manager.SendFileManager;
import com.android.yinghebike.manager.SendFileManager1;
import com.hjq.permissions.OnPermissionCallback;
import com.yanzhenjie.permission.runtime.Permission;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import butterknife.BindView;
import butterknife.OnClick;
import cn.wandersnail.ble.Device;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.EventObserver;
import cn.wandersnail.ble.Request;
import cn.wandersnail.commons.util.StringUtils;

//升级页面
public class UpdateActivity extends BaseActivity {

    @BindView(R.id.comm_title)
    Comm_HeadView comm_title;
    @BindView(R.id.recyclerview)
    RecyclerView recyclerview;
    @BindView(R.id.ctv_device)
    Comm_TitleView ctv_device;
    @BindView(R.id.ctv_file)
    Comm_TitleView ctv_file;
    @BindView(R.id.pb_percent)
    ProgressBar pb_percent;
    @BindView(R.id.tv_percent)
    TextView tv_percent;
    @BindView(R.id.csb_begin)
    Comm_SubmitBtnView csb_begin;

    public static String Tag_SendFile = "SendFile";
    public static String Tag_SendData = "SendData";
    public static String Tag_SendBegin = "Tag_SendBegin";

    LogAdapter logAdapter;
    List<String> logList = new ArrayList<>();
    SendFileManager sendFileManager;
    SendFileManager1 sendFileManager1;
    File file;
    int sendFileType = 0;   //文件类型

    @Override
    protected int getLayoutId() {
        return R.layout.activity_update;
    }

    @Override
    protected void initView() {
        comm_title.setTitle(getString(R.string.mine_update));

        recyclerview.setLayoutManager(new LinearLayoutManager(mContext));
        logAdapter = new LogAdapter(mContext, new CommCallBack() {
            @Override
            public void onResult(Object obj) {
                recyclerview.scrollToPosition(logAdapter.getItemCount() - 1);
            }
        });
        recyclerview.setAdapter(logAdapter);
        logAdapter.setData(logList);

        sendFileManager = new SendFileManager(mContext);
        sendFileManager.setLogAdapter(logAdapter);
        sendFileManager.setCallBack_progress(progressCallBack);

        sendFileManager1 = new SendFileManager1(mContext);
        sendFileManager1.setLogAdapter(logAdapter);
        sendFileManager1.setCallBack_progress(progressCallBack);


    }

    //进度回调
    CommCallBack progressCallBack = new CommCallBack() {
        @Override
        public void onResult(Object obj) {
            float percent = (float) obj;
            pb_percent.setProgress((int) percent);
            tv_percent.setText(Util.formatDouble(percent, 2, 0) + "%");
            if (percent == 100) {
                canExit(true);
            }
        }
    };

    //是否可以退出， 升级开始后，不让退出
    private void canExit(boolean canExit) {
        if (canExit) {
            csb_begin.setVisibility(View.VISIBLE);
            comm_title.setLeftImgVisible(View.VISIBLE);
            CommToast.showToast(mContext, getString(R.string.comm_tips_success));

        } else {
            csb_begin.setVisibility(View.GONE);
            comm_title.setLeftImgVisible(View.GONE);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (BleManager.getInstance().isConnect()) {
            ctv_device.setContent(BleManager.getInstance().deviceInfo.getName());
        } else {
            ctv_device.setContent(getString(R.string.update_unselect));
        }
    }

    @Override
    protected void initData() {


        EasyBLE.getInstance().registerObserver(eventObserver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EasyBLE.getInstance().unregisterObserver(eventObserver);
    }

    //蓝牙事件
    EventObserver eventObserver = new EventObserver() {
        @Override
        public void onConnectionStateChanged(@NonNull Device device) {
            EventObserver.super.onConnectionStateChanged(device);
            switch (device.getConnectionState()) {
                case SCANNING_FOR_RECONNECTION:

                    break;
                case CONNECTING:
                    Log.i("连接中...");
                    break;
                case DISCONNECTED:
                    Log.i("连接断开");
//                    tv_bluetooth_state.setText("未连接");
                    CommToast.showToast(mContext, "设备已断开");
                    break;
                case SERVICE_DISCOVERED:
                    Log.i("连接成功");
//                    tv_bluetooth_state.setText("已连接");
                    CommToast.showToast(mContext, "设备已连接");
                    break;
            }
        }

        @Override
        public void onCharacteristicWrite(@NonNull Request request, @NonNull byte[] value) {
            String hexStr = StringUtils.toHex(value, " ");
            if (request.getTag().equals(Tag_SendFile)) {
                Log.d("成功发送小包：" + value.length + ":" + hexStr);
                SystemClock.sleep(50);
                if (sendFileType == 0) {
                    sendFileManager.sendSmallBag();
                } else {
                    sendFileManager1.sendSmallBag();
                }
            } else if (request.getTag().equals(Tag_SendData)) {
                Log.d("成功发送文字数据：" + hexStr);
                logAdapter.addLog(">>> 文字发送成功：" + hexStr);
            } else if (request.getTag().equals(Tag_SendBegin)) {
                Log.d("成功发送开始数据：" + hexStr);
                logAdapter.addLog(">>> 已发送开始指令，等待回复");
            }
        }

        @Override
        public void onCharacteristicRead(@NonNull Request request, @NonNull byte[] value) {
            String hexStr = StringUtils.toHex(value, " ");
            Log.w("收到设备主动发送来的数据:" + hexStr);
            logAdapter.addLog("<<< 收到数据：" + hexStr);

        }

        @Override
        public void onCharacteristicChanged(@NonNull Device device, @NonNull UUID service, @NonNull UUID characteristic, @NonNull byte[] value) {
            String hexStr = StringUtils.toHex(value, " ");
            Log.w("收到设备主动发送来的数据:" + hexStr);
            if (value.length == 1) {
                if (value[0] == (byte) 0x4B) {
                    logAdapter.addLog("<<< 收到主机回复：" + hexStr + "，开始发送数据");
                    canExit(false);
                    sendFileType = 0;


                    sendFileManager.setFile(file, new CommCallBack() {
                        @Override
                        public void onResult(Object obj) {
                            sendFileManager.sendBigBag();
                        }
                    });
                }
                else if (value[0] == (byte) 0x53) {
                    logAdapter.addLog("<<< 收到主机回复：" + hexStr + "，开始发送数据");
                    canExit(false);
                    sendFileType = 1;

                    sendFileManager1.setFile(file);
                    sendFileManager1.sendBigBag();
                } else if (value[0] == (byte) 0x35) {
                    logAdapter.addLog("<<< 收到主机回复：" + hexStr + "，继续发送数据");
                    if (sendFileType == 0) {
                        sendFileManager.sendBigBag();
                    } else {
                        sendFileManager1.sendBigBag();
                    }
                } else {
                    logAdapter.addLog("<<< 收到主机回复：" + hexStr + "，数据校验失败");
                    canExit(true);
                }
            } else {
                logAdapter.addLog("<<< 收到数据：" + hexStr);
            }
        }
    };

    @OnClick({R.id.ctv_file, R.id.csb_begin, R.id.ctv_device})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.ctv_file:   //选择文件
                getPermission();
                break;
            case R.id.csb_begin:
                //发送开始命令
                if (!BleManager.getInstance().isConnect()) {
                    CommToast.showToast(mContext, "请连接蓝牙设备");
                    return;
                }
                if (file == null) {
                    CommToast.showToast(mContext, "请选择文件");
                    return;
                }

                byte[] data = {(byte) 0x55};
                BleManager.getInstance().sendData(data, Tag_SendBegin);
                break;
            case R.id.ctv_device:
                StartActivity(Device_ListActivity.class);
                break;
        }
    }

    // region  选文件
    final int REQUEST_CODE_FOR_DIR = 100;
    final int REQUEST_CODE_FOR_File = 200;

    //获取权限    安卓 29 = 安卓11
    private void getPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
            //没有权限, 跳设置
            try {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.addCategory("android.intent.category.DEFAULT");
                intent.setData(Uri.parse(String.format("package:%s", mContext.getPackageName())));
                startActivityForResult(intent, REQUEST_CODE_FOR_DIR);
            } catch (Exception e) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                startActivityForResult(intent, REQUEST_CODE_FOR_DIR);
            }
        } else {
            XXPermisionUtil.requstPermision(mContext, new OnPermissionCallback() {
                @Override
                public void onGranted(List<String> permissions, boolean all) {
                    selectFile();
                }

                @Override
                public void onDenied(List<String> permissions, boolean never) {
                    OnPermissionCallback.super.onDenied(permissions, never);
                    CommToast.showToast(mContext, "没有文件读取权限");
                }
            }, Permission.READ_EXTERNAL_STORAGE);
        }
    }

    //从系统选择文件，限制文件类型 .bin
    private void selectFile() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"application/octet-stream"});
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, REQUEST_CODE_FOR_File);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_FOR_DIR:   //返回授权信息
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    if (Environment.isExternalStorageManager()) {
                        CommToast.showToast(mContext, "权限获取成功,请选择文件");
                        getPermission();
                    } else {
                        CommToast.showToast(mContext, "权限获取失败");
                    }
                }
                break;
            case REQUEST_CODE_FOR_File:   //返回获取文件
                if (data != null) {
                    Uri uri = data.getData();
                    Log.i("uri.getPath:" + uri.getPath());
                    String path = FileUriUtil.getPath(mContext, uri);
                    file = new File(path);

                    ctv_file.setContent(path);
                    logAdapter.addLog("选择文件：" + path);

                }
                break;
        }
    }

    // endregion

}
